package com.mcxx.modules.temporary.salary.service.write;

import cn.hutool.core.date.DateUtil;
import com.mcxx.common.exception.BizException;
import com.mcxx.convert.FormulCountParamConvert;
import com.mcxx.formulcount.param.FormulCountParam;
import com.mcxx.modules.formulcount.FormulCountService;
import com.mcxx.modules.miniSalvation.order.dto.PropertiesDTO;
import com.mcxx.modules.miniSalvation.order.service.read.PropertiesReadService;
import com.mcxx.modules.miniSalvation.order.service.read.StandardReadService;
import com.mcxx.modules.temporary.family.dto.TmpFamilyMemberDTO;
import com.mcxx.modules.temporary.family.service.read.TmpFamilyMemberReadService;
import com.mcxx.modules.temporary.order.dto.GoodsDTO;
import com.mcxx.modules.temporary.order.dto.TmpOrderDTO;
import com.mcxx.modules.temporary.order.dto.TmpAuditDTO;
import com.mcxx.modules.temporary.order.service.read.TmpOrderReadService;
import com.mcxx.modules.temporary.salary.entity.TmpFamilySalaryEntity;
import com.mcxx.modules.temporary.salary.dao.write.TmpFamilySalaryWriteDao;
import com.mcxx.modules.temporary.salary.entity.TmpMemberSalaryEntity;
import com.mcxx.result.BaseResult;
import com.mcxx.util.CommonUtil;
import com.mcxx.util.Constant;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@TaTransactional
public class TmpFamilySalaryWriteService {

    @Autowired
    private TmpFamilySalaryWriteDao tmpFamilySalaryWriteDao;
    @Autowired
    private TmpMemberSalaryWriteService tmpMemberSalaryWriteService;
    @Autowired
    private StandardReadService standardReadService;
    @Autowired
    private PropertiesReadService propertiesReadService;
    @Autowired
    private TmpFamilyMemberReadService tmpFamilyMemberReadService;
    @Autowired
    private TmpOrderReadService tmpOrderReadService;
    @Autowired
    private FormulCountService formulCountService;


    public int insert(TmpFamilySalaryEntity tmpFamilySalary) {
    	return tmpFamilySalaryWriteDao.insert(tmpFamilySalary);
    }


    public int insertIgnoreNull(TmpFamilySalaryEntity tmpFamilySalary) {
    	return tmpFamilySalaryWriteDao.insertIgnoreNull(tmpFamilySalary);
    }


    public int update(TmpFamilySalaryEntity tmpFamilySalary) {
    	return tmpFamilySalaryWriteDao.update(tmpFamilySalary);
    }


    public int updateIgnoreNull(TmpFamilySalaryEntity tmpFamilySalary) {
    	return tmpFamilySalaryWriteDao.updateIgnoreNull(tmpFamilySalary);
    }


    public void saveFamilySalary(TmpAuditDTO tmpAuditDTO, UserAccountVo userAccountVo){

        this.packageCalcSalaryParam(tmpAuditDTO);


        this.calcSalary(tmpAuditDTO, userAccountVo);


        this.saveSalaryInfo(tmpAuditDTO);


        this.getOnethingCheckType(userAccountVo, tmpAuditDTO);
    }


    private void calcSalary(TmpAuditDTO tmpAuditDTO, UserAccountVo userAccountVo){
        switch (tmpAuditDTO.getSalvType()){

            case "400":
                this.calcFamilySalaryByGoodsType(tmpAuditDTO);

            case "204":
                if(CommonUtil.invalidArgs(tmpAuditDTO.getSalvMoney())){
                    throw new BizException(FailureCode.ERR_70001);
                }
                break;

            default:
                this.calcSalaryBySalvationRule(userAccountVo, tmpAuditDTO);
                break;
        }
    }


    public void packageCalcSalaryParam(TmpAuditDTO tmpAuditDTO){


        TmpOrderDTO tmpOrderDTO = tmpOrderReadService.getOrderSarlayInfo(tmpAuditDTO.getOrderId());


        tmpAuditDTO.setName(tmpOrderDTO.getName());
        tmpAuditDTO.setFamilyId(tmpOrderDTO.getFamilyId());
        tmpAuditDTO.setIdcard(tmpOrderDTO.getIdcard());
        tmpAuditDTO.setAreaCode(tmpOrderDTO.getAreaCode());
        tmpAuditDTO.setMainReason(tmpOrderDTO.getMainReason());
    }


    private void calcFamilySalaryByGoodsType(TmpAuditDTO tmpAuditDTO){

        BigDecimal sumSalvMoney = new BigDecimal(0);
        for (GoodsDTO goodsDTO : tmpAuditDTO.getGoodsList()){
            BigDecimal unit = new BigDecimal(goodsDTO.getUnit());
            BigDecimal number = new BigDecimal(goodsDTO.getNumber());
            BigDecimal subtotal = unit.multiply(number);
            goodsDTO.setSubtotal(subtotal.doubleValue());
            sumSalvMoney = sumSalvMoney.add(subtotal);
        }
        tmpAuditDTO.setSalvMoney(sumSalvMoney.doubleValue());
    }


    public void getOnethingCheckType(UserAccountVo userAccountVo, TmpAuditDTO tmpAuditDTO){

        if(CommonUtil.invalidArgs(tmpAuditDTO.getSalvMoney())){
            throw new BizException(FailureCode.ERR_70001);
        }


        Map<String, BigDecimal> standardMoneyMap = standardReadService.getMaxMinStandardMoney(userAccountVo.getAreaCode().substring(0, 6)+ "000000", Constant.BusinessCode.DIBAO);
        Double maxStandardMoney = standardMoneyMap.get("maxStandardMoney").doubleValue();
        Double minStandardMoney = standardMoneyMap.get("minStandardMoney").doubleValue();

        PropertiesDTO propertiesDTO = propertiesReadService.getConfigByAreaCode(userAccountVo.getAreaCode().substring(0, 6), "救急难标准");
        if(null == propertiesDTO){

            propertiesDTO = new PropertiesDTO();
            propertiesDTO.setConfigType("0");
        }

        if(null != propertiesDTO){
            switch (propertiesDTO.getConfigType()){

                case "0":
                    if(tmpAuditDTO.getSalvMoney() > maxStandardMoney * 6 * tmpAuditDTO.getSaveMemberNumber()){

                        tmpAuditDTO.setOnethingCheckType("1");
                    }else{

                        tmpAuditDTO.setOnethingCheckType("0");
                    }
                    break;

                case "1":
                    if(tmpAuditDTO.getSalvMoney() > maxStandardMoney * 6 * tmpAuditDTO.getSaveMemberNumber()
                            || tmpAuditDTO.getSalvMoney() < propertiesDTO.getSalaryNumber()){

                        tmpAuditDTO.setOnethingCheckType("1");
                    }else{

                        tmpAuditDTO.setOnethingCheckType("0");
                    }
                    break;
            }
        }
    }


    public void calcSalaryBySalvationRule(UserAccountVo userAccountVo, TmpAuditDTO tmpAuditDTO){

        Map<String, Double> masterSocietyNumMap = tmpOrderReadService.getMasterSocietyNum(tmpAuditDTO.getIdcard(), DateUtil.formatDate(DateUtil.beginOfYear(new Date())));


        FormulCountParam formulCountParam = FormulCountParamConvert.convertOrderSalaryDTO(masterSocietyNumMap, userAccountVo, tmpAuditDTO);


        BaseResult<Map<String,Object>> securityRst = formulCountService.salvationFormulCount(formulCountParam);
        if("300".equals(securityRst.getCode()) || "400".equals(securityRst.getCode())){
            throw new BizException(securityRst.getCode(), securityRst.getMsg());
        }else if("0".equals(securityRst.getCode()) == false){

            throw new BizException(FailureCode.ERR_20017);
        }

        Map<String,Object> map = securityRst.getData();
        if(null == map || map.size() <= 0){
            throw new BizException(FailureCode.ERR_20017);
        }

        for (String k : map.keySet()){
            tmpAuditDTO.setSalvMoney(Double.parseDouble(map.get(k).toString()));
        }
    }


    private void saveSalaryInfo(TmpAuditDTO tmpAuditDTO){

        tmpFamilySalaryWriteDao.deleteByOrderId(tmpAuditDTO.getOrderId());
        tmpMemberSalaryWriteService.deleteByOrderId(tmpAuditDTO.getOrderId());


        TmpFamilySalaryEntity familySalaryEntity = FormulCountParamConvert.convertFamilySalaryEntity(tmpAuditDTO);
        tmpFamilySalaryWriteDao.insert(familySalaryEntity);


        List<TmpMemberSalaryEntity> tmpMemberSalaryList = new ArrayList<>();

        List<TmpFamilyMemberDTO> familyMemberList = tmpFamilyMemberReadService.getByFamilyId(tmpAuditDTO.getFamilyId(), Constant.IsSaveObject.YES);
        familyMemberList.forEach(familyMember->{
            tmpMemberSalaryList.add(FormulCountParamConvert.convertMemberSalaryEntity(tmpAuditDTO, familyMember));
        });
        tmpMemberSalaryWriteService.insertSalarys(tmpMemberSalaryList);
    }


    public String getOnethingCheckType(UserAccountVo userAccountVo, String orderId, double salvMoney){

        TmpOrderDTO tmpOrderDTO = tmpOrderReadService.getOrderSarlayInfo(orderId);


        TmpAuditDTO auditDTO = new TmpAuditDTO();
        auditDTO.setSaveMemberNumber(tmpOrderDTO.getSaveMemberNumber());
        auditDTO.setSalvMoney(salvMoney);


        this.getOnethingCheckType(userAccountVo, auditDTO);


        return auditDTO.getOnethingCheckType();
    }


    public int deleteSalaryByOrderId(String orderId) {
        tmpMemberSalaryWriteService.deleteByOrderId(orderId);
        return tmpFamilySalaryWriteDao.deleteByOrderId(orderId);
    }


    public int updateIgnoreNullByOrderId(TmpFamilySalaryEntity tmpFamilySalaryEntity) {
        return tmpFamilySalaryWriteDao.updateIgnoreNullByOrderId(tmpFamilySalaryEntity);

    }

}
